using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

using Zsa.Emulation.Cartridge;



namespace Zsa.Emulation.CNes.UI
{
    /// <summary>
    /// Used to find files on file system.
    /// </summary>
    public partial class FileSystemRomBrowserControl : RomBrowserControl
    {
        #region Fields
        /// <summary>
        /// The cartridge file info.
        /// </summary>
        private List<CartridgeFileInfo> _Cartridges = new List<CartridgeFileInfo>();
        //private FileSystemWatcher
        #endregion Fields

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="FileSystemRomBrowserControl"/> class.
        /// </summary>
        public FileSystemRomBrowserControl()
        {
            InitializeComponent();
        }
        #endregion Constructors



        #region Methods

        /// <summary>
        /// Refreshes the rom list.
        /// </summary>
        public override void RefreshRoms()
        {
            UpdateList(textBoxDirectory.Text);
        }

        /// <summary>
        /// Updates the list.
        /// </summary>
        /// <param name="path">The path.</param>
        private void UpdateList(string path)
        {
            ToggleControls(false);
            textBoxDirectory.Text = path;
            backgroundWorker1.RunWorkerAsync(path);
        }

        /// <summary>
        /// Toggles the controls.
        /// </summary>
        /// <param name="enabled">if set to <c>true</c> [enabled].</param>
        private void ToggleControls(bool enabled)
        {
            buttonBrowse.Enabled = enabled;
            cartListControl1.Enabled = enabled;
            cartInfoControl1.Enabled = enabled;
            // clear the controls.
        }
        
        /// <summary>
        /// Raises the <see cref="E:System.Windows.Forms.UserControl.Load"></see> event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs"></see> that contains the event data.</param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            UpdateList(Config.NesConfigurationManager.Profiles.LastRomFilePath);
        }

        #region Event Handlers
        /// <summary>
        /// Handles the Click event of the buttonBrowse control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void buttonBrowse_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog1.ShowDialog() != DialogResult.OK)
            {
                return;
            }
            UpdateList(folderBrowserDialog1.SelectedPath);
        }

        /// <summary>
        /// Handles the DoWork event of the backgroundWorker1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.ComponentModel.DoWorkEventArgs"/> instance containing the event data.</param>
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            if ( e.Argument == null )
            {
                throw new NullReferenceException("The path name cannot be null !");
            }
            
            

            // Get the rom path.
            string _Path = e.Argument.ToString();
            // Add the nes file extensions
            List<string> _Files = 
                new List<string>(
                Directory.GetFiles(_Path,"*.nes",SearchOption.TopDirectoryOnly)
                );

            // Add the nes file extensions
            _Files.AddRange(
                Directory.GetFiles(_Path,"*.rom",SearchOption.TopDirectoryOnly)
                );

            //CartridgeFileInfoCollection _CartInfo = DumpManager.ScanFiles(_Files.ToArray(), null);
            //_CartInfo = _CartInfo.Filter(Zsa.Emulation.Mappers.MapperTypeNumber.None);
            //_CartInfo.CopyRoms(@"C:\Roms\nomapper");


            // Create the cartridge temp list.
            List<CartridgeFileInfo> _CartridgeTemp = new List<CartridgeFileInfo>(_Files.Count);

            // The number used to find when to report a percentage changed.
            int _ReportMod = (int)Math.Ceiling(_Files.Count / 100D);

            CartridgeFileInfo _CartFileTemp;
            
            // The current file index.
            for ( int _FileIndex = 0; _FileIndex < _Files.Count && !e.Cancel; _FileIndex++ )
            {
                if ( !DumpManager.TryGetCartInfo(_Files[_FileIndex], out _CartFileTemp) ) 
                {
                    continue;
                }
                _CartridgeTemp.Add(_CartFileTemp);
                if ( (_FileIndex % _ReportMod) == 0 )
                {
                    backgroundWorker1.ReportProgress(
                        _FileIndex / _ReportMod
                    );
                }
            }
            if (!e.Cancel)
            {
                e.Result = _CartridgeTemp;
            }

        }

        /// <summary>
        /// Handles the ProgressChanged event of the backgroundWorker1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.ComponentModel.ProgressChangedEventArgs"/> instance containing the event data.</param>
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // This is updated.  Add a status counter thing later or something.
        }

        /// <summary>
        /// Handles the RunWorkerCompleted event of the backgroundWorker1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.ComponentModel.RunWorkerCompletedEventArgs"/> instance containing the event data.</param>
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                ToggleControls(true);
                return;
            }
            if (e.Error != null)
            {
                ToggleControls(true);
                return;
            }
            List<CartridgeFileInfo> _FileInfo = e.Result as List<CartridgeFileInfo>;
            if (_FileInfo == null)
            {
                ToggleControls(true);
                return;
            }
            cartListControl1.SetCartList(_FileInfo);
            _Cartridges = _FileInfo;
            ToggleControls(true);
            
        }
        /// <summary>
        /// Carts the list control1_ cart selected.
        /// </summary>
        /// <param name="obj">The obj.</param>
        private void cartListControl1_CartSelected(CartridgeFileInfo obj)
        {
            cartInfoControl1.ShowInfo(obj);
            OnCartSelected(obj);
        }
        #endregion Event Handlers



        #endregion Methods

        public override object DirectoryKey
        {
            get
            {
                return textBoxDirectory.Text;
            }
        }
    }
}
